package com.yunxin.customui.bean.table;

import com.yunxin.tools.commonbean.DataBean;
import com.yunxin.tools.commonbean.exceptions.GeneralException;
import com.yunxin.tools.commonbean.tips.TipsMessage;
import com.yunxin.customui.bean.table.methodresult.ComDataResult;
import com.yunxin.customui.bean.table.methodresult.GetTableBeanResult;
import com.yunxin.customui.bean.table.methodresult.ListDataBeansResult;
import com.yunxin.customui.bean.table.datatable.TableBusinessConfig;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 功能描述:
 *    自定义表格获取数据模板流程
 * date 2021/8/4 9:30
 *
 * @author cc
 * @version 1.0
 */
public abstract class AbstractTableDataTemplate {

    //1通过tableId获取表格配置对象
    public abstract TableBusinessConfig getVTableConfigBean(Integer tableId);

    //通过plantIdx,genIdx获取dataId
    public abstract List<String> getDataIds(TableBusinessConfig tableDataConfig, Integer plantIdx, Integer genIdx);
    // 通过filter字段过滤多余的点号池
    public abstract List<String> filterIds(TableBusinessConfig tableDataConfig, List<String> ids);

    //通过ids、开始时间、结束时间获取数据集合
    public abstract Map<String, ListDataBeansResult> getListDataBeans(TableBusinessConfig tableDataConfig, List<String> dataIds, String beginTime, String endTime) throws Exception;

    //补数据（错位填坑）
    public abstract List<ComDataResult> comData(TableBusinessConfig tableDataConfig, Map<String,Integer> dataIdsAndTimeInterval, Map<String,List<DataBean>> mapDataBeans, String beginTime, String endTime);

    //对获取到的数据进行处理
    public abstract List<List<DataBean>> handleListDataBeans(TableBusinessConfig tableDataConfig, List<List<DataBean>> listDataBeans) ;



    //将数据集合转换为TableBean结构
    public abstract TableBean changeDataStructure(TableBusinessConfig tableDataConfig, List<List<DataBean>> listDataBeans);

    //最终个性化处理
    public abstract TableBean handleTableBean(TableBusinessConfig tableDataConfig, TableBean tableBean);

    //方法调用中心
    public GetTableBeanResult getTableBean(Integer tableId,List<String> dataIds,String beginTime,String endTime) throws Exception {
        GetTableBeanResult getTableBeanResult = new GetTableBeanResult();
        //收集异常信息 state=2的
        List<TipsMessage> messages = new ArrayList<>();
        getTableBeanResult.setTipsMessageList(messages);
        //表的配置信息
        TableBusinessConfig tableDataConfig = getVTableConfigBean(tableId);

        if (tableDataConfig.getTableDataTemplates().size() == 0){
            throw new GeneralException("该表格还没有配置列信息");
        }
        long l1 = System.currentTimeMillis();
        // 增加筛选池子的功能
        if(tableDataConfig.getFilter() != null && !tableDataConfig.getFilter().equals("")){
            dataIds = filterIds(tableDataConfig, dataIds);
            if(dataIds.isEmpty()){
                throw new GeneralException("筛选完点号后，点号为空，请查询点号配置");
            }
        }
        long l2 = System.currentTimeMillis();
        //*获取数据，得到map<Id,数据返回包装对象（其中有数据，过程异常情况提示信息）集合>
        Map<String,ListDataBeansResult> mapDataBeans = getListDataBeans(tableDataConfig,dataIds, beginTime, endTime);
        long l3 = System.currentTimeMillis();

        //将上一步的结果处理为下一步 所需要的数据格式 , 收集提示信息
        Map<String,Integer> idAndTimeIntervalMap = new HashMap<>();
        List<List<DataBean>> listComResult = new ArrayList<>();
        Map<String,List<DataBean>> mapDataBean = new HashMap<>();
        for (Map.Entry<String, ListDataBeansResult> entry : mapDataBeans.entrySet()) {
            idAndTimeIntervalMap.put(entry.getKey(), entry.getValue().getTimeInterval());
            listComResult.add(entry.getValue().getDataBeans());
            messages.addAll(entry.getValue().getMessageList());
            mapDataBean.put(entry.getKey(),entry.getValue().getDataBeans());
        }

        //如果合并-合并完直接转table
        //如果不可并 ，则将表格数据对齐，再转table
        List<List<DataBean>> listList = new ArrayList<>();
        if (!tableDataConfig.getMergeType().contains("不合并")){
            listList = handleListDataBeans(tableDataConfig, listComResult);
        }else {
            //进行补数据，根据vTableConfigBean的配置信息 数据类型和 merge类型 进行不同类型的补数据
            List<ComDataResult> comDataResults = comData(tableDataConfig, idAndTimeIntervalMap, mapDataBean, beginTime, endTime);
            //将上一步的结果处理为下一步 所需要的数据格式 ， 收集提示信息
            listList = new ArrayList<>();
            for (ComDataResult comDataResult : comDataResults) {
                messages.addAll(comDataResult.getMsgList());
                listList.add(comDataResult.getDataBeans());
            }
        }
        long l4 = System.currentTimeMillis();
        // 把数据转换成表格
        TableBean tableBean = changeDataStructure(tableDataConfig, listList);
        long l5 = System.currentTimeMillis();
        // 对表格列合计，表格样式，表头做最终处理
        TableBean finalTableBean = handleTableBean(tableDataConfig, tableBean);
        getTableBeanResult.setTableBean(finalTableBean);
        long l6 = System.currentTimeMillis();
        System.out.println("过滤耗时="+(l2-l1));
        System.out.println("取数据耗时="+(l3-l2));
        System.out.println("合并与数据对其耗时="+(l4-l3));
        System.out.println("转表格耗时="+(l5-l4));
        System.out.println("最终处理耗时="+(l6-l5));
        System.out.println("总耗时="+(l6-l1));
        return getTableBeanResult;
    }
}
